package gcp;

import gcp.enums.ClassificacaoEtaria;
import gcp.enums.GeneroFilme;
import gcp.enums.ItemEstado;

import java.io.Serializable;

/**
 * Classe Filme do Projeto GCP.
 */
public class Filme implements Colecionavel, Serializable {

    private static final long serialVersionUID = 1L;
    private int ano;
    private String titulo;
    private String comentarios;
    private String quemPublicou;
    private ClassificacaoEtaria classificacaoEtaria;
    private ItemEstado itemEstado;
    private GeneroFilme genero;
    private int nota;

    /**
     * Cria um objeto filme.
     */
    public Filme() {
    }

    /**
     * Cria um objeto filme.
     * @param titulo Titulo do filme.
     * @param quemPublicou Quem publicou o filme.
     * @param ano O ano em que o filme foi publicado.
     * @param classificacaoEtaria A classificacao etaria do filme.
     * @param itemEstado O estado em que o film se encontra.
     * @param genero O genero do filme.
     * @param comentarios Comentarios sobre o filme.
     * @throws Exception Lancada quando algum parametro for invalido.
     */
    public Filme(String titulo, String quemPublicou, int ano,
            ClassificacaoEtaria classificacaoEtaria, ItemEstado itemEstado,
            GeneroFilme genero, String comentarios) throws Exception {
        if (titulo == null || titulo.isEmpty())
            throw new Exception("O titulo não pode ser nulo.");
        if (quemPublicou == null || quemPublicou.isEmpty())
            throw new Exception("Quem publicou não pode ser nulo.");
        if (ano <= 0)
            throw new Exception("Ano não pode ser nulo ou negativo.");
        this.ano = ano;
        this.comentarios = comentarios;
        this.classificacaoEtaria = classificacaoEtaria;
        this.genero = genero;
        this.quemPublicou = quemPublicou;
        this.itemEstado = itemEstado;
        this.titulo = titulo;
    }

    /**
     * Retorna o ano em que o filme foi publicado.
     * @return O ano em que o filme foi publicado.
     */
    public int getAno() {
        return ano;
    }

    /**
     * Retorna os comentarios feitos a respeito do filme.
     * @return comentarios Os comentarios a respeito do filme.
     */
    public String getComentarios() {
        return comentarios;
    }

    /**
     * Retorna a classificacao etaria do filme.
     * @return classificacaoEtaria A classificacao etaria do filme.
     */
    public ClassificacaoEtaria getClassificacaoEtaria() {
        return classificacaoEtaria;
    }

    /**
     * Retorna o estado em que o filme se encontra.
     * @return itemEstado O estado em que o filme se encontra.
     */
    public ItemEstado getItemEstado() {
        return itemEstado;
    }

    /**
     * Retorna quem publicou o filme.
     * @return quemPublicou Quem publicou o filme.
     */
    public String getQuemPublicou() {
        return quemPublicou;
    }

    /**
     * Retorna o titulo do filme.
     * @return titulo O titulo do filme .
     */
    public String getTitulo() {
        return titulo;
    }

    /**
     * Atualiza o genero do filme para o passado como parametro.
     * @param genero O genero do filme a ser atualizado.
     */
    public void setGeneroDoFilme(GeneroFilme genero) {
        this.genero = genero;
    }

    /**
	 * Atualiza o ano de publicacao do colecionavel para o passado como parametro.
	 * @param ano O ano de publicacao do colecionavel a ser atualizado.
     * @throws Exception Lancada quando o ano for negativo.
	 */
    public void setAno(int ano) throws Exception {
        this.ano = ano;
    }

    /**
	 * Atualiza os cometarios em relacao ao colecionavel para o passado como parametro.
	 * @param comentarios Os cometarios sobre o colecionavel a ser atualizado.
     * @throws Exception Lancada quando o comentario for vazio ou nulo.
	 */
    public void setComentarios(String comentarios) throws Exception {
        this.comentarios = comentarios;
    }

    /**
	 * Atualiza a classificacao etaria do colecionavel para a passada como parametro.
	 * @param classificacaoEtaria - A classificacao etaria do colecionavel a ser atualizada.
	 */
    public void setClassificacaoEtaria(ClassificacaoEtaria classificacaoEtaria) {
        this.classificacaoEtaria = classificacaoEtaria;
    }

    /**
	 * Atualiza o estado do colecionavel para o passado como parametro.
	 * @param itemEstado O estado do colecionavel a ser atualizado.
	 */
    public void setItemEstado(ItemEstado itemEstado) {
        this.itemEstado = itemEstado;
    }

    /**
	 * Atualiza quem publicou o colecionavel para o passado como parametro.
	 * @param quemPublicou Quem publicou o colecionavel.
     * @throws Exception Lancada quando o parametro for vazio ou nulo.
	 */
    public void setQuemPublicou(String quemPublicou) throws Exception {
        this.quemPublicou = quemPublicou;
    }

    /**
	 * Atualiza o titulo do colecionavel para o passado como parametro.
	 * @param titulo O titulo do colecionavel a ser atualizado.
     * @throws Exception Lancada quando o titulo for vazio ou nulo.
	 */
    public void setTitulo(String titulo) throws Exception {
        this.titulo = titulo;
    }

    /**
     * Retorna o genero ao qual o filme se caracteriza.
     * @return genero o genero ao qual o filme se caracteriza.
     */
    public GeneroFilme getGenero() {
        return genero;
    }

    /**
     * Atualiza o genero ao qual o filme se caracteriza para o passado como parametro.
     * @param genero O genero ao qual o filme se caracteriza a ser atualizado.
     */
    public void setGenero(GeneroFilme genero) {
        this.genero = genero;
    }

    /**
	 * Atualiza a nota do colecionavel, em relacao a sua qualidade, para a passada como parametro.
	 * @param nota A nota dada ao colecionavel a ser atualizada.
     * @throws Exception Lancada quando o ano for negativo.
	 */
    public void setNota(int nota) throws Exception {
        this.nota = nota;
    }

    /**
	 * Retorna a nota do colecionavel em relacao a sua qualidade.
	 * @return nota A nota dada ao colecionavel que vai de 0 a 4.
	 */
    public int getNota() {
        return nota;
    }

    /**
     * Gera um hashCode para Filme.
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((titulo == null) ? 0 : titulo.hashCode());
        return result;
    }

    /**
     * Retorna uma representacao String para Filme.
     */
    @Override
    public String toString() {
        return "Filme - " + titulo;
    }

    /**
     * Verifica se um Filme eh igual ao objeto passado como parametro.
     * @param obj - O objeto a ser comparado.
     * @return True, em caso de semelhanca, e false caso contrario.
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Filme other = (Filme) obj;
        if (titulo == null) {
            if (other.titulo != null)
                return false;
        } else if (!titulo.equals(other.titulo))
            return false;
        return true;
    }
}